package com.lgh.hotel.handler.security;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.lgh.hotel.dao.pojo.SysUser;
import com.lgh.hotel.service.SysUserService;
import com.lgh.hotel.vo.Result;
import io.jsonwebtoken.Claims;
import io.jsonwebtoken.ExpiredJwtException;
import io.jsonwebtoken.Jwts;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.autoconfigure.security.SecurityProperties;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.security.authentication.AuthenticationManager;
import org.springframework.security.authentication.UsernamePasswordAuthenticationToken;
import org.springframework.security.core.GrantedAuthority;
import org.springframework.security.core.authority.AuthorityUtils;
import org.springframework.security.core.authority.SimpleGrantedAuthority;
import org.springframework.security.core.context.SecurityContextHolder;
import org.springframework.security.web.authentication.www.BasicAuthenticationFilter;
import org.springframework.stereotype.Component;

import javax.servlet.FilterChain;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.io.PrintWriter;
import java.io.UnsupportedEncodingException;
import java.util.ArrayList;
import java.util.List;

@Slf4j
//@Component
public class HandlerAuthenticationFilter extends BasicAuthenticationFilter {

    @Autowired
    SysUserService sysUserService;

    private RedisTemplate<String,String> redisTemplate;

    public HandlerAuthenticationFilter(AuthenticationManager authenticationManager,RedisTemplate template) {

        //必须是第一条语句
        super(authenticationManager);

        this.redisTemplate = template;

    }

    @Override
    protected void doFilterInternal(HttpServletRequest request, HttpServletResponse response, FilterChain chain) throws IOException, ServletException {

        String auth = request.getHeader("Authorization");

        if (auth == null || auth.length()<=0){
            chain.doFilter(request,response);
            return;
        }
        String userJson = redisTemplate.opsForValue().get("TOKEN_"+auth);
        if (userJson == null || userJson.length() <= 0){
            response.setContentType("application/json;charset=utf-8");
            PrintWriter writer = response.getWriter();
            writer.write(JSONObject.toJSONString(Result.fail("用户token失效！")));
            writer.flush();
            writer.close();
            throw new UnsupportedEncodingException("用户token失效！");
        }

        SysUser sysUser = JSONObject.parseObject(userJson, SysUser.class);
        log.info("访问用户:{}",sysUser.getUsername());
        List<GrantedAuthority> grantedAuthorities = AuthorityUtils.commaSeparatedStringToAuthorityList(sysUser.getRoles());
        UsernamePasswordAuthenticationToken usernamePasswordAuthenticationToken = new UsernamePasswordAuthenticationToken(sysUser.getUsername(), null, grantedAuthorities);
        SecurityContextHolder.getContext().setAuthentication(usernamePasswordAuthenticationToken);
        chain.doFilter(request,response);
    }

//    private UsernamePasswordAuthenticationToken getAuthentication(String jwt, HttpServletResponse response) {
//
//        try {
//            Claims claims
//                    = Jwts.parser()
//                    .setSigningKey(SecretKeyUtil.generalKey())
//                    .parseClaimsJws(jwt).getBody();
//            //获取存储在claims中的用户信息
//            String json = claims.get(SecurityKey.USER_CONTEXT).toString();
//            AuthUser authUser = JSON.parseObject(json, AuthUser.class);
//
//            //校验redis中是否有权限
//            Boolean hasKey = redisTemplate.hasKey(CachePrefix.ACCESS_TOKEN.name() + UserEnums.MEMBER.name() + jwt);
//            if (hasKey != null && hasKey) {
//                //构造返回信息
//                List<GrantedAuthority> auths = new ArrayList<>();
//                auths.add(new SimpleGrantedAuthority("ROLE_" + authUser.getRole().name()));
//                UsernamePasswordAuthenticationToken authentication = new UsernamePasswordAuthenticationToken(authUser.getUsername(), null, auths);
//                authentication.setDetails(authUser);
//                return authentication;
//            }
//            ResponseUtil.output(response, 401, Result.noLogin());
//            return null;
//        } catch (ExpiredJwtException e) {
//            log.debug("user analysis exception:", e);
//        } catch (Exception e) {
//            log.error("user analysis exception:", e);
//        }
//        ResponseUtil.output(response, 401, Result.noLogin());
//        return null;
//    }
}
